package com.yanqu.road.server.manager.activity.snowgarden;

import com.yanqu.road.dao.impl.servercenter.ActivityDaoImpl;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.snowgarden.config.SnowGardenBuyConfig;
import com.yanqu.road.entity.activity.snowgarden.config.SnowGardenFakeBuyInfo;
import com.yanqu.road.entity.config.goods.MallInfo;
import com.yanqu.road.logic.bussiness.servercenter.ActivityBussiness;
import com.yanqu.road.utils.date.DateHelper;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

public class SnowGardenFakeBuyConfig {
    private int activityId;
    private ActivityInfo activityInfo;
    //key=mallKey
    private Map<Integer, SnowGardenBuyConfig> buyConfigMap = new HashMap<>();
    private Map<Integer, MallInfo> mallInfoMap = new HashMap<>();
    //缓存每次的目标数,key=mallId
    private Map<Integer, Integer> nowRandTargetNumMap = new HashMap<>();
    //缓存下次的检查时间,秒,key=mallId
    private Map<Integer, Long> nextCheckTimeMap = new HashMap<>();
    private Random random = new Random();


    public SnowGardenFakeBuyConfig(ActivityInfo activityInfo) {
        this.activityId = activityInfo.getActivityId();
        this.activityInfo = activityInfo;
        loadDb();
    }

    public void loadDb() {
        Map<Integer, SnowGardenBuyConfig> tempBuyConfigMap = ActivityBussiness.getServerBuyMallConfig(activityInfo.getActivityId());
        Map<Integer, MallInfo> tempMallInfoMap = new ActivityDaoImpl().getActivityMallInfoMap(activityId);

        Map<Integer, MallInfo> tempMallInfoNeedMap = new HashMap<>();
        for (MallInfo mallInfo : tempMallInfoMap.values()) {
            int mallKey = Integer.parseInt(mallInfo.getExtendParam());
            if (mallKey == 0) {
                continue;
            }
            tempMallInfoNeedMap.put(mallInfo.getMallId(), mallInfo);
        }

        buyConfigMap = tempBuyConfigMap;
        mallInfoMap = tempMallInfoNeedMap;
    }

    public int getActivityId() {
        return activityId;
    }

    public ActivityInfo getActivityInfo() {
        return activityInfo;
    }

    /**
     * 获得当前时间对应的小时数字,活动的beginTime开始的第N个小时,或者beginTime后，每天0点开始的第N个小时,N从1开始
     * 这个方法会更新下一次的检查时间
     *
     * @return
     */
    public int calcNowHourNum(int mallId) {
        SnowGardenBuyConfig buyConfig = getBuyConfig(mallId);
        if (buyConfig == null) {
            return 0;
        }
        long currentSecond = DateHelper.getCurrentTime() / 1000;
        if (currentSecond < activityInfo.getBeginTime() || currentSecond > activityInfo.getEndTime()) {
            return 0;
        }
        long todayZeroSecond = DateHelper.getTodayZeroTimeStamp() / 1000; //当天0点秒
        if (todayZeroSecond <= activityInfo.getBeginTime()) {
            //活动开始时间在今天0点之后
            int hourNum = (int) ((currentSecond - activityInfo.getBeginTime()) / buyConfig.getJudgeTime()) + 1;
            return hourNum;
        } else {
            //活动开始时间在今天0点之前
            int hourNum = (int) ((currentSecond - todayZeroSecond) / buyConfig.getJudgeTime()) + 1;
            return hourNum;
        }
    }

    public long calcAndGetNextCheckTime(int mallId) {
        SnowGardenBuyConfig buyConfig = getBuyConfig(mallId);
        if (buyConfig == null) {
            return 0;
        }
        long currentSecond = DateHelper.getCurrentTime() / 1000;
        if (currentSecond < activityInfo.getBeginTime() || currentSecond > activityInfo.getEndTime()) {
            return 0;
        }
        long nextCheckTime = nextCheckTimeMap.getOrDefault(mallId, 0L);
        if (nextCheckTime > currentSecond) {
            return nextCheckTime;
        }
        long todayZeroSecond = DateHelper.getTodayZeroTimeStamp() / 1000; //当天0点秒
        if (todayZeroSecond > activityInfo.getBeginTime()) {
            //活动开始时间在今天0点之后
            long hourNum = ((currentSecond - activityInfo.getBeginTime()) / buyConfig.getJudgeTime()) + 1;
            nextCheckTime = activityInfo.getBeginTime() + hourNum * buyConfig.getJudgeTime();
            nextCheckTimeMap.put(mallId, nextCheckTime);
            nowRandTargetNumMap.remove(mallId);
            return nextCheckTime;
        } else {
            //活动开始时间在今天0点之前
            long hourNum = ((currentSecond - todayZeroSecond) / buyConfig.getJudgeTime()) + 1;
            nextCheckTime = todayZeroSecond + hourNum * buyConfig.getJudgeTime();
            nextCheckTimeMap.put(mallId, nextCheckTime);
            nowRandTargetNumMap.remove(mallId);
            return nextCheckTime;
        }
    }

    public MallInfo getMallInfo(int mallId) {
        return mallInfoMap.get(mallId);
    }

    public SnowGardenBuyConfig getBuyConfig(int mallId) {
        MallInfo mallInfo = getMallInfo(mallId);
        if (mallInfo == null) {
            return null;
        }
        int mallKey = Integer.parseInt(mallInfo.getExtendParam());
        SnowGardenBuyConfig buyConfig = buyConfigMap.get(mallKey);
        return buyConfig;
    }


    public int getTargetNum(int mallId) {
        MallInfo mallInfo = getMallInfo(mallId);
        if (mallInfo == null) {
            return 0;
        }
        SnowGardenBuyConfig buyConfig = getBuyConfig(mallId);
        if (buyConfig == null) {
            return 0;
        }
        long nextCheckTime = calcAndGetNextCheckTime(mallId);
        if (nextCheckTime <= 0) {
            return 0;
        }
        long currentSecond = DateHelper.getCurrentTime() / 1000;
        if (currentSecond < nextCheckTime && nowRandTargetNumMap.containsKey(mallId)) {
            return nowRandTargetNumMap.get(mallId);
        }

        int hourNum = calcNowHourNum(mallId);
        SnowGardenFakeBuyInfo fakeBuyInfo = buyConfig.getFakeBuyInfo(hourNum);
        if (fakeBuyInfo == null) {
//            CrossActivityMallDayBuyConfigMgr.getLogger().error("SnowGardenFakeBuyConfig getTargetNum fakeBuyInfo is null,activityId={},mallId={},hourNum={}", activityId, mallId, hourNum);
            return 0;
        }

        int startRandNum = fakeBuyInfo.getStartRandNum();
        int endRandNum = fakeBuyInfo.getEndRandNum();
        //随机一下
        int targetNum = random.nextInt(endRandNum - startRandNum + 1) + startRandNum;
        nowRandTargetNumMap.put(mallId, targetNum);
        return targetNum;
    }

    public int getAddFakeBuyCountOnce(int mallId, int hourNum) {
        SnowGardenBuyConfig buyConfig = getBuyConfig(mallId);
        if (buyConfig == null) {
            return 0;
        }
        SnowGardenFakeBuyInfo fakeBuyInfo = buyConfig.getFakeBuyInfo(hourNum);
        if (fakeBuyInfo == null) {
//            CrossActivityMallDayBuyConfigMgr.getLogger().error("SnowGardenFakeBuyConfig getOnceAdd fakeBuyInfo is null,activityId={},mallId={},hourNum={}", activityId, mallId, hourNum);
            return 0;
        }
        int addFakeBuyCountOnceMin = fakeBuyInfo.getAddFakeBuyCountOnceMin();
        int addFakeBuyCountOnceMax = fakeBuyInfo.getAddFakeBuyCountOnceMax();
        int addCount = random.nextInt(addFakeBuyCountOnceMax - addFakeBuyCountOnceMin + 1) + addFakeBuyCountOnceMin;
        return addCount;
    }

    /**
     * 获得计算假购买计算的开始时间
     *
     * @param mallId
     * @return
     */
    public long getStartCheckTime(int mallId) {
        long nextCheckTime = calcAndGetNextCheckTime(mallId);
        if (nextCheckTime <= 0) {
            return 0;
        }
        SnowGardenBuyConfig buyConfig = getBuyConfig(mallId);
        if (buyConfig == null) {
            return 0;
        }
        return nextCheckTime - buyConfig.getJudgeTime();
    }

    /**
     * 根据上一次加假进度的时间判断当前时间是否要加假进度
     *
     * @param mallId
     * @param lastAddFakeTime 上一次加假进度的时间 秒
     * @return
     */
    public boolean isNeedAddFakeCount(int mallId, long lastAddFakeTime) {
        long currentSecond = DateHelper.getCurrentTime() / 1000;
        if (currentSecond < lastAddFakeTime) {
            return false;
        }
        long startCheckTime = getStartCheckTime(mallId);
        if (startCheckTime <= 0) {
            return false;
        }
        if (currentSecond < startCheckTime) {
            return false;
        }

        SnowGardenBuyConfig buyConfig = getBuyConfig(mallId);
        if (buyConfig == null) {
            return false;
        }
        long interval = buyConfig.getIntervalTime();
        long nowPassCount = (currentSecond - startCheckTime) / interval;
        long lastPassCount = (lastAddFakeTime - startCheckTime) / interval;
        if (nowPassCount > lastPassCount) {//当前时间经过的间隔数和上一次加的时间经过的间隔不一样
            return true;
        }
        return false;
    }

    public Map<Integer, MallInfo> getMallInfoMap() {
        return mallInfoMap;
    }
}
